Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


tests/backend/conftest.py 22b4fcce096023ec706bab5449805e34a2912643 (22b4fcce) Text, 10.67 KB

T8b949e# SPDX-License-Identifier: 0BSD

Tff7b72import T7ee787asyncio
Tff7b72import T7ee787os

T8b949e# Disable Landlock sandbox globally during backend testing to prevent process lockdown and PermissionError crashes.
Te6edf3osTff7b72.Td2a8ffenvironTb4b4b4[Ta5d6ff"Ta5d6ffMESHCHAT_LANDLOCKTa5d6ff"Tb4b4b4] Tff7b72= Ta5d6ff"Ta5d6ff0Ta5d6ff"
T8b949e# Disable Windows AppContainer launcher path in tests (no-op on Linux, safe on Windows CI).
Te6edf3osTff7b72.Td2a8ffenvironTb4b4b4[Ta5d6ff"Ta5d6ffMESHCHAT_APPCONTAINERTa5d6ff"Tb4b4b4] Tff7b72= Ta5d6ff"Ta5d6ff0Ta5d6ff"

Tff7b72import T7ee787socket
Tff7b72from T7ee787contextlib Tff7b72import Te6edf3ExitStack
Tff7b72from T7ee787unittestT7ee787.T7ee787mock Tff7b72import Te6edf3MagicMockTb4b4b4, Te6edf3patch

Tff7b72import T7ee787pytest
Tff7b72import T7ee787RNS

Tff7b72from T7ee787meshchatxT7ee787.T7ee787meshchat Tff7b72import Te6edf3ReticulumMeshChat
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787config_manager Tff7b72import Te6edf3ConfigManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787database Tff7b72import Te6edf3Database
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787provider Tff7b72import Te6edf3DatabaseProvider
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787schema Tff7b72import Te6edf3DatabaseSchema
Tff7b72from T7ee787testsT7ee787.T7ee787backendT7ee787.T7ee787supportT7ee787.T7ee787test_temp_dir Tff7b72import Tb4b4b4(
Te6edf3TEST_COVERAGE_DIRTb4b4b4,
Te6edf3ensure_test_temp_dirsTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ff_ensure_coverage_data_dirTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Te6edf3ensure_test_temp_dirsTb4b4b4(Tb4b4b4)
Te6edf3cov_file Tff7b72= Te6edf3osTff7b72.Td2a8ffenvironTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffCOVERAGE_FILETa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3cov_fileTb4b4b4:
Tff7b72return
Te6edf3parent Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffdirnameTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffabspathTb4b4b4(Te6edf3cov_fileTb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3parentTb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3parentTb4b4b4, Te6edf3exist_okTff7b72=Tff7b72TrueTb4b4b4)


Te6edf3_ensure_coverage_data_dirTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffpytest_configureTb4b4b4(Te6edf3configTb4b4b4)Tb4b4b4:
Te6edf3ensure_test_temp_dirsTb4b4b4(Tb4b4b4)
Te6edf3_ensure_coverage_data_dirTb4b4b4(Tb4b4b4)
Te6edf3worker Tff7b72= Te6edf3osTff7b72.Td2a8ffenvironTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffPYTEST_XDIST_WORKERTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3workerTb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3TEST_COVERAGE_DIRTb4b4b4, Te6edf3exist_okTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3osTff7b72.Td2a8ffenvironTb4b4b4[Ta5d6ff"Ta5d6ffCOVERAGE_FILETa5d6ff"Tb4b4b4] Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(
Tffa657strTb4b4b4(Te6edf3TEST_COVERAGE_DIRTb4b4b4)Tb4b4b4,
Ta5d6fffTa5d6ff"Ta5d6ff.coverage.Tffd700{Te6edf3workerTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8fffixtureTb4b4b4(Te6edf3scopeTff7b72=Ta5d6ff"Ta5d6ffsessionTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffloopback_availableTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3server Tff7b72= Te6edf3socketTff7b72.Td2a8ffsocketTb4b4b4(Te6edf3socketTff7b72.Td2a8ffAF_INETTb4b4b4, Te6edf3socketTff7b72.Td2a8ffSOCK_STREAMTb4b4b4)
Te6edf3client Tff7b72= Te6edf3socketTff7b72.Td2a8ffsocketTb4b4b4(Te6edf3socketTff7b72.Td2a8ffAF_INETTb4b4b4, Te6edf3socketTff7b72.Td2a8ffSOCK_STREAMTb4b4b4)
Te6edf3accepted Tff7b72= Tff7b72None
Tff7b72tryTb4b4b4:
Te6edf3serverTff7b72.Td2a8ffsettimeoutTb4b4b4(T79c0ff0.5Tb4b4b4)
Te6edf3clientTff7b72.Td2a8ffsettimeoutTb4b4b4(T79c0ff0.5Tb4b4b4)
Te6edf3serverTff7b72.Td2a8ffbindTb4b4b4(Tb4b4b4(Ta5d6ff"Ta5d6ff127.0.0.1Ta5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4)
Te6edf3serverTff7b72.Td2a8fflistenTb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3port Tff7b72= Te6edf3serverTff7b72.Td2a8ffgetsocknameTb4b4b4(Tb4b4b4)Tb4b4b4[T79c0ff1Tb4b4b4]
Te6edf3clientTff7b72.Td2a8ffconnectTb4b4b4(Tb4b4b4(Ta5d6ff"Ta5d6ff127.0.0.1Ta5d6ff"Tb4b4b4, Te6edf3portTb4b4b4)Tb4b4b4)
Te6edf3acceptedTb4b4b4, Te6edf3_ Tff7b72= Te6edf3serverTff7b72.Td2a8ffacceptTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72True
Tff7b72except Tf85149OSErrorTb4b4b4:
Tff7b72return Tff7b72False
Tff7b72finallyTb4b4b4:
Tff7b72if Te6edf3accepted Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3acceptedTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Te6edf3clientTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Te6edf3serverTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8ffrequire_loopback_tcpTb4b4b4(Te6edf3loopback_availableTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3loopback_availableTb4b4b4:
Te6edf3pytestTff7b72.Td2a8ffskipTb4b4b4(
Ta5d6ff"Ta5d6ffLoopback TCP is blocked by local firewall/policy; skipping localhost integration test.Ta5d6ff"Tb4b4b4,
Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8fffixtureTb4b4b4(Te6edf3autouseTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72def Td2a8ffglobal_mocksTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72with Tb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.meshchat.AsyncUtilsTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3mock_async_utilsTb4b4b4,
Te6edf3patchTb4b4b4(
Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.IdentityContext.start_background_threadsTa5d6ff"Tb4b4b4,
Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.meshchat.generate_ssl_certificateTa5d6ff"Tb4b4b4, Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4:
T8b949e# Mock run_async to properly close coroutines
Tff7b72def Td2a8ffmock_run_asyncTb4b4b4(Te6edf3coroTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3asyncioTff7b72.Td2a8ffiscoroutineTb4b4b4(Te6edf3coroTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
T8b949e# If it's a coroutine, we should close it if it's not being awaited
Te6edf3coroTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149RuntimeErrorTb4b4b4:
Tff7b72pass
Tff7b72elif Tffa657hasattrTb4b4b4(Te6edf3coroTb4b4b4, Ta5d6ff"Ta5d6ff__await__Ta5d6ff"Tb4b4b4)Tb4b4b4:
T8b949e# Handle other awaitables
Tff7b72pass

Te6edf3mock_async_utilsTff7b72.Td2a8ffrun_asyncTff7b72.Td2a8ffside_effect Tff7b72= Te6edf3mock_run_async

Tff7b72yield Tb4b4b4{
Ta5d6ff"Ta5d6ffasync_utilsTa5d6ff"Tb4b4b4: Te6edf3mock_async_utilsTb4b4b4,
Tb4b4b4}


Tf0883e@pytestTff7b72.Td2a8fffixtureTb4b4b4(Te6edf3autouseTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72def Td2a8ffcleanup_sqlite_connectionsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72yield
Tff7b72import T7ee787gc

Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ff_uses_real_lxst_telephoneTb4b4b4(Te6edf3requestTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72return Te6edf3requestTff7b72.Td2a8ffnodeTff7b72.Td2a8ffget_closest_markerTb4b4b4(Ta5d6ff"Ta5d6fflxst_realTa5d6ff"Tb4b4b4) Tff7b72is Tff7b72not Tff7b72None


Tf0883e@pytestTff7b72.Td2a8fffixtureTb4b4b4(Te6edf3autouseTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72def Td2a8ffstub_lxst_telephone_unless_realTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
T8b949e"""Avoid LXST background announce threads during ReticulumMeshChat tests."""
Tff7b72if Te6edf3_uses_real_lxst_telephoneTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72yield
Tff7b72return

Te6edf3mock_instance Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3mock_instanceTff7b72.Td2a8ffbusy Tff7b72= Tff7b72False
Te6edf3mock_instanceTff7b72.Td2a8ffcall_status Tff7b72= T79c0ff3
Te6edf3mock_instanceTff7b72.Td2a8ffactive_call Tff7b72= Tff7b72None
Te6edf3mock_instanceTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffhexhash Tff7b72= Ta5d6ff"Ta5d6fftest_telephone_hexhashTa5d6ff"
Tff7b72with Te6edf3patchTb4b4b4(
Ta5d6ff"Ta5d6ffmeshchatx.src.backend.telephone_manager.TelephoneTa5d6ff"Tb4b4b4,
Te6edf3return_valueTff7b72=Te6edf3mock_instanceTb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72yield Te6edf3mock_instance


Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8fftemp_dbTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3db_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3tmp_pathTb4b4b4, Ta5d6ff"Ta5d6fftest_meshchat.dbTa5d6ff"Tb4b4b4)
Tff7b72yield Te6edf3db_path
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3db_pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3db_pathTb4b4b4)


Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8ffdbTb4b4b4(Te6edf3temp_dbTb4b4b4)Tb4b4b4:
Te6edf3provider Tff7b72= Te6edf3DatabaseProviderTb4b4b4(Te6edf3temp_dbTb4b4b4)
Te6edf3schema Tff7b72= Te6edf3DatabaseSchemaTb4b4b4(Te6edf3providerTb4b4b4)
Te6edf3schemaTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Te6edf3database Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3temp_dbTb4b4b4)
Tff7b72yield Te6edf3database
Te6edf3databaseTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)
Te6edf3providerTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8ffmock_appTb4b4b4(Te6edf3dbTb4b4b4, Te6edf3tmp_pathTb4b4b4, Te6edf3temp_dbTb4b4b4)Tb4b4b4:
Te6edf3real_identity_class Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentity

Tff7b72class T56d364MockIdentityClassTb4b4b4(Te6edf3real_identity_classTb4b4b4)Tb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhash Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6fftest_hash_32_bytes_long_01234567Ta5d6ff"
Tff7b72selfTff7b72.Td2a8ffhexhash Tff7b72= Tff7b72selfTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)

Tff7b72with Te6edf3ExitStackTb4b4b4(Tb4b4b4) Tff7b72as Te6edf3stackTb4b4b4:
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffRNS.IdentityTa5d6ff"Tb4b4b4, Te6edf3MockIdentityClassTb4b4b4)Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffRNS.ReticulumTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffRNS.TransportTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffLXMF.LXMRouterTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.TelephoneManagerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.VoicemailManagerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.RingtoneManagerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.RNCPHandlerTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.RnsFilesyncHandlerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.RNStatusHandlerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.RNProbeHandlerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.TranslatorHandlerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.ArchiverManagerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.MapManagerTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.MessageHandlerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.identity_context.AnnounceManagerTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffthreading.ThreadTa5d6ff"Tb4b4b4)Tb4b4b4)
T8b949e# threading.Thread is mocked to prevent background threads, but that also
T8b949e# breaks asyncio.to_thread (used by the HTTP layer for DB queries). Run
T8b949e# those calls synchronously so integration tests do not hang waiting for a
T8b949e# MagicMock thread that never starts.
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTb4b4b4(
Ta5d6ff"Ta5d6ffasyncio.to_threadTa5d6ff"Tb4b4b4,
Te6edf3side_effectTff7b72=Tff7b72lambda Te6edf3fnTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4: Te6edf3fnTb4b4b4(Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Te6edf3mock_id Tff7b72= Te6edf3MockIdentityClassTb4b4b4(Tb4b4b4)
Te6edf3mock_idTff7b72.Td2a8ffget_private_key Tff7b72= Te6edf3MagicMockTb4b4b4(Te6edf3return_valueTff7b72=Ta5d6ffbTa5d6ff"Ta5d6fftest_private_keyTa5d6ff"Tb4b4b4)

Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(Te6edf3MockIdentityClassTb4b4b4, Ta5d6ff"Ta5d6fffrom_fileTa5d6ff"Tb4b4b4, Te6edf3return_valueTff7b72=Te6edf3mock_idTb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(Te6edf3MockIdentityClassTb4b4b4, Ta5d6ff"Ta5d6ffrecallTa5d6ff"Tb4b4b4, Te6edf3return_valueTff7b72=Te6edf3mock_idTb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(Te6edf3MockIdentityClassTb4b4b4, Ta5d6ff"Ta5d6fffrom_bytesTa5d6ff"Tb4b4b4, Te6edf3return_valueTff7b72=Te6edf3mock_idTb4b4b4)Tb4b4b4,
Tb4b4b4)

Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(
Te6edf3ReticulumMeshChatTb4b4b4,
Ta5d6ff"Ta5d6ffannounce_loopTa5d6ff"Tb4b4b4,
Te6edf3newTff7b72=Te6edf3MagicMockTb4b4b4(Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(
Te6edf3ReticulumMeshChatTb4b4b4,
Ta5d6ff"Ta5d6ffannounce_sync_propagation_nodesTa5d6ff"Tb4b4b4,
Te6edf3newTff7b72=Te6edf3MagicMockTb4b4b4(Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(
Te6edf3ReticulumMeshChatTb4b4b4,
Ta5d6ff"Ta5d6ffcrawler_loopTa5d6ff"Tb4b4b4,
Te6edf3newTff7b72=Te6edf3MagicMockTb4b4b4(Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(
Te6edf3ReticulumMeshChatTb4b4b4,
Ta5d6ff"Ta5d6ffauto_backup_loopTa5d6ff"Tb4b4b4,
Te6edf3newTff7b72=Te6edf3MagicMockTb4b4b4(Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(
Te6edf3ReticulumMeshChatTb4b4b4,
Ta5d6ff"Ta5d6fflocal_message_retention_loopTa5d6ff"Tb4b4b4,
Te6edf3newTff7b72=Te6edf3MagicMockTb4b4b4(Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3stackTff7b72.Td2a8ffenter_contextTb4b4b4(
Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(
Te6edf3ReticulumMeshChatTb4b4b4,
Ta5d6ff"Ta5d6ffsend_config_to_websocket_clientsTa5d6ff"Tb4b4b4,
Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Te6edf3app Tff7b72= Te6edf3ReticulumMeshChatTb4b4b4(
Te6edf3identityTff7b72=Te6edf3mock_idTb4b4b4,
Te6edf3storage_dirTff7b72=Tffa657strTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4,
Te6edf3reticulum_config_dirTff7b72=Tffa657strTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4,
Tb4b4b4)

T8b949e# DatabaseProvider is a singleton; IdentityContext.setup() opens the identity DB
T8b949e# and replaces the singleton. Recreate the test DB handle so config and DAOs use
T8b949e# a live provider for the same path as the db fixture.
Te6edf3appTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3temp_dbTb4b4b4)
Te6edf3appTff7b72.Td2a8ffcurrent_contextTff7b72.Td2a8ffconfig Tff7b72= Te6edf3ConfigManagerTb4b4b4(Te6edf3appTff7b72.Td2a8ffdatabaseTb4b4b4)
Te6edf3appTff7b72.Td2a8ffconfig Tff7b72= Te6edf3appTff7b72.Td2a8ffcurrent_contextTff7b72.Td2a8ffconfig
Tff7b72if Te6edf3appTff7b72.Td2a8ffrrc_manager Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3appTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffset_databaseTb4b4b4(Te6edf3appTff7b72.Td2a8ffdatabaseTb4b4b4)
Te6edf3appTff7b72.Td2a8ffwebsocket_broadcast Tff7b72= Te6edf3MagicMockTb4b4b4(Te6edf3side_effectTff7b72=Tff7b72lambda Te6edf3dataTb4b4b4: Tff7b72NoneTb4b4b4)
Te6edf3appTff7b72.Td2a8ffdemo_mode Tff7b72= Tff7b72False
Te6edf3appTff7b72.Td2a8ffaltcha_enabled Tff7b72= Tff7b72False

Tff7b72yield Te6edf3app
Te6edf3appTff7b72.Td2a8ffteardown_identityTb4b4b4(Tb4b4b4)


Tff7b72async Tff7b72def Td2a8fffetch_api_csrf_headersTb4b4b4(Te6edf3clientTb4b4b4)Tb4b4b4:
Te6edf3response Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/auth/csrfTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3responseTff7b72.Td2a8ffstatus Tff7b72== T79c0ff200
Te6edf3payload Tff7b72= Tff7b72await Te6edf3responseTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3token Tff7b72= Te6edf3payloadTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcsrf_tokenTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3token
Tff7b72return Tb4b4b4{Ta5d6ff"Ta5d6ffX-CSRF-TokenTa5d6ff"Tb4b4b4: Te6edf3tokenTb4b4b4}


Tff7b72def Td2a8ffextend_meshchat_middlewaresTb4b4b4(Te6edf3aio_appTb4b4b4, Te6edf3middlewaresTb4b4b4)Tb4b4b4:
Te6edf3auth_mwTb4b4b4, Te6edf3mime_mwTb4b4b4, Te6edf3sec_mwTb4b4b4, Te6edf3csrf_mwTb4b4b4, Te6edf3ip_mwTb4b4b4, Te6edf3demo_mw Tff7b72= Te6edf3middlewares
Te6edf3aio_appTff7b72.Td2a8ffmiddlewaresTff7b72.Td2a8ffextendTb4b4b4(Tb4b4b4[Te6edf3auth_mwTb4b4b4, Te6edf3mime_mwTb4b4b4, Te6edf3sec_mwTb4b4b4, Te6edf3csrf_mwTb4b4b4, Te6edf3ip_mwTb4b4b4, Te6edf3demo_mwTb4b4b4]Tb4b4b4)


Tff7b72def Td2a8ffpytest_collection_modifyitemsTb4b4b4(Te6edf3sessionTb4b4b4, Te6edf3configTb4b4b4, Te6edf3itemsTb4b4b4)Tb4b4b4:
Te6edf3shard_index Tff7b72= Te6edf3osTff7b72.Td2a8ffenvironTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffPYTEST_SHARD_INDEXTa5d6ff"Tb4b4b4)
Te6edf3total_shards Tff7b72= Te6edf3osTff7b72.Td2a8ffenvironTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffPYTEST_TOTAL_SHARDSTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3shard_index Tff7b72is Tff7b72not Tff7b72None Tff7b72and Te6edf3total_shards Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3shard_index Tff7b72= Tffa657intTb4b4b4(Te6edf3shard_indexTb4b4b4)
Te6edf3total_shards Tff7b72= Tffa657intTb4b4b4(Te6edf3total_shardsTb4b4b4)
Tff7b72if Te6edf3total_shards Tff7b72> T79c0ff1 Tff7b72and T79c0ff0 Tff7b72<Tff7b72= Te6edf3shard_index Tff7b72< Te6edf3total_shardsTb4b4b4:
Te6edf3itemsTff7b72.Td2a8ffsortTb4b4b4(Te6edf3keyTff7b72=Tff7b72lambda Te6edf3itemTb4b4b4: Te6edf3itemTff7b72.Td2a8ffnodeidTb4b4b4)
Te6edf3itemsTb4b4b4[Tb4b4b4:Tb4b4b4] Tff7b72= Tb4b4b4[
Te6edf3item
Tff7b72for Te6edf3iTb4b4b4, Te6edf3item Tff7b72in Tffa657enumerateTb4b4b4(Te6edf3itemsTb4b4b4)
Tff7b72if Te6edf3i Tff7b72% Te6edf3total_shards Tff7b72== Te6edf3shard_index
Tb4b4b4]
Tff7b72except Tf85149ValueErrorTb4b4b4:
Tff7b72pass


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────